package com.bistu.xiong.common.widget.recycler;

import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.bistu.xiong.common.R;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * Created by XiongXiaoJun on 2017/12/18.
 * RecyclerAdapter适配器的封装
 */

public abstract class RecyclerAdapter<Data> extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder<Data>>
            implements View.OnClickListener, View.OnLongClickListener,AdapterCallback<Data>{
    private final List<Data> mDataList;
    private AdapterListener<Data> mListener;
    protected Context context;

    public RecyclerAdapter() {
        this(null);
    }
    public RecyclerAdapter(AdapterListener<Data> listener) {
        this(new ArrayList<Data>(), listener,null);
    }

    protected RecyclerAdapter(List<Data> mDataList, AdapterListener<Data> mListener,Context context) {
        this.mDataList = mDataList;
        this.mListener = mListener;
        this.context = context;
    }
    /**
     * 设置适配器的监听
     * @param adapterListener AdapterListener
     */
    public void setListener(AdapterListener<Data> adapterListener) {
        this.mListener = adapterListener;
    }

    @Override
    public void onClick(View v) {
        ViewHolder viewHolder = (ViewHolder) v.getTag(R.id.tag_recycler_holder);
        if (this.mListener != null) {
            // 得到ViewHolder当前对应的适配器中的坐标
            int pos = viewHolder.getAdapterPosition();
            // 回掉方法
            this.mListener.onItemClick(viewHolder, mDataList.get(pos));
        }

    }

    @Override
    public boolean onLongClick(View v) {
        ViewHolder viewHolder = (ViewHolder) v.getTag(R.id.tag_recycler_holder);
        if (this.mListener != null) {
            // 得到ViewHolder当前对应的适配器中的坐标
            int pos = viewHolder.getAdapterPosition();
            // 回掉方法
            this.mListener.onItemLongClick(viewHolder, mDataList.get(pos));
            return true;
        }
        return false;
    }

    /**
     * 插入一条数据并通知插入
     * @param data
     */
    public void add(Data data){
        mDataList.add(data);
        //更新所有的Item
//        notifyDataSetChanged();
        //只对某个位置进行更新
        notifyItemInserted(mDataList.size()-1);
    }

    /**
     * 插入一堆数据，并通知这段集合更新
     * @param dataList
     */
    public void add(Data... dataList){
        if (dataList!=null && dataList.length>0){
            int startPos = mDataList.size();
            Collections.addAll(mDataList, dataList);
            notifyItemRangeInserted(startPos,dataList.length);
        }
    }

    /**
     * 插入一堆数据，并通知这段集合更新
     * @param dataList Data
     */
    public void add(Collection<Data> dataList){
        if (dataList!=null && dataList.size()>0){
            int startPos = mDataList.size();
            mDataList.addAll(dataList);
            notifyItemRangeInserted(startPos,dataList.size());
        }
    }

    /**
     * 删除操作
     */
    public void clear() {
        mDataList.clear();
        notifyDataSetChanged();
    }

    /**
     * 替换为一个新的集合，其中包括了清空
     * @param dataList 一个新的集合
     */
    public void replace(List<Data> dataList) {
        mDataList.clear();
        if (dataList == null || dataList.size() == 0)
            return;
        mDataList.addAll(dataList);
        notifyDataSetChanged();
    }

    @Override
    public void update(Data data, ViewHolder<Data> holder) {
        //得到当前ViewHolder的坐标
        int pos = holder.getAdapterPosition();
        if(pos>=0){
            //进行数据移除与更新
            mDataList.remove(pos);
            mDataList.add(pos,data);
            //通知刷新
            notifyItemChanged(pos);
        }
    }


    @Override
    public int getItemViewType(int position) {
        return getItemViewType(position,mDataList.get(position));
    }

    /**
     * 得到布局的类型
     * @param position 坐标
     * @param data 当前的数据
     * @return 根据当前的数据返回 XML文件的ID，用于创建ViewHolder
     */
    @LayoutRes
    protected abstract int getItemViewType(int position,Data data);

    @Override
    public int getItemCount() {
        return mDataList==null?0:mDataList.size();
    }

    //约定viewType作为Xml的Id
    @Override
    public ViewHolder<Data> onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View root = inflater.inflate(viewType,parent,false);
        ViewHolder<Data> holder = onCreateViewHolder(root,viewType);
        //界面注解
        holder.unbinder = ButterKnife.bind(holder,root);

        //设置View的Tag为ViewHolder,进行双向的绑定
        root.setTag(R.id.tag_recycler_holder,holder);

        //设置事件点击
        root.setOnClickListener(this);
        root.setOnLongClickListener(this);



        //绑定callback
        holder.callback = this;
        return holder;
    }

    protected abstract ViewHolder<Data> onCreateViewHolder(View root,int viewType);

    @Override
    public void onBindViewHolder(ViewHolder<Data> holder, int position) {
        Data data = mDataList.get(position);
        holder.bind(data);
    }

    /**
     * 自定义的ViewHOlder
     * @param <Data> 泛型类型
     */
    public static abstract class ViewHolder<Data> extends RecyclerView.ViewHolder{
        private Unbinder unbinder;
        private AdapterCallback<Data> callback;
        protected Data mData;
        protected Context context;
        public ViewHolder(View itemView) {
            this(null,itemView);
        }
        public ViewHolder(Context context,View itemView) {
            super(itemView);
            this.context = context;
        }
        void bind(Data data){
            this.mData = data;
            onBind(data);
        }
        protected abstract void onBind(Data data);
        public void updateData(Data data){
            if (this.callback!=null){
                this.callback.update(data,this);
            }
        }
    }

    /**
     * 我们的自定义监听器
     * @param <Data> 范型
     */
    public interface AdapterListener<Data> {
        // 点击的时候触发
        void onItemClick(RecyclerAdapter.ViewHolder holder, Data data);
        // 长按时触发
        void onItemLongClick(RecyclerAdapter.ViewHolder holder, Data data);
    }

    /**
     * 对回调接口做一次实现
     * @param <Data>
     */
    public static abstract class AdapterListenerImpl<Data> implements AdapterListener<Data>{

        @Override
        public void onItemClick(ViewHolder holder, Data data) {

        }

        @Override
        public void onItemLongClick(ViewHolder holder, Data data) {

        }
    }
}
